//
//  ImageUtil.swift
//  Extend
//
//  Created by shufang zou on 2017/8/22.
//  Copyright © 2017年 敬信. All rights reserved.
//

import Foundation
import Accelerate
import Photos

public extension UIImage {
    
    //    根据颜色生成Image
    public class func setColor(_ color: UIColor?) -> UIImage {
        let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor((color?.cgColor)!)
        context?.fill(rect)
        var image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return (image ?? UIImage())!
    }
    
    public class func setColor(_ color: UIColor?, width: CGFloat, height: CGFloat) -> UIImage {
        let rect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor((color?.cgColor)!)
        context?.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return (image ?? UIImage())!
    }
    
    /// 根据颜色组生成渐变Image
    ///
    /// - Parameters:
    ///   - rect: 大小
    ///   - colors: 颜色
    ///   - type: 方向 0：从上到下 1：从左到右
    /// - Returns: image
    public class func setGradientImageWithBounds(rect: CGRect, colors: Array<UIColor>, type: Int) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(rect.size, true, 0)
        let context = UIGraphicsGetCurrentContext()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let colors = colors.map {(color: UIColor) -> AnyObject! in return color.cgColor as AnyObject! } as NSArray
        let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: nil)
        // 第二个参数是起始位置，第三个参数是终止位置
        if type == 0 {
            //从上到下
            context!.drawLinearGradient(gradient!, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: rect.size.height), options: CGGradientDrawingOptions(rawValue: 0))
        } else {
            //从左到右
            context!.drawLinearGradient(gradient!, start: CGPoint(x: 0, y: 0), end: CGPoint(x: rect.size.width, y: 0), options: CGGradientDrawingOptions(rawValue: 0))
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return (image ?? UIImage())!
    
    }
    
    public static func image(with size: CGSize, borderColor color: UIColor, borderWidth: CGFloat, radius: CGFloat, length: CGFloat) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        UIColor.clear.set()
        let context: CGContext! = UIGraphicsGetCurrentContext()
        context.beginPath()
        context.setLineWidth(borderWidth)
        context.setStrokeColor(color.cgColor)
        context.setLineDash(phase: 0, lengths: [length, length])

        //四根线
        context.move(to: CGPoint(x: 0 + radius, y: 0))
        context.addLine(to: CGPoint(x: size.width - radius, y: 0.0))

        context.move(to: CGPoint(x: size.width, y: 0 + radius))
        context.addLine(to: CGPoint(x: size.width, y: size.height - radius))

        context.move(to: CGPoint(x: size.width - radius, y: size.height))
        context.addLine(to: CGPoint(x: 0  + radius, y: size.height))

        context.move(to: CGPoint(x: 0, y: size.height - radius))
        context.addLine(to: CGPoint(x: 0.0, y: 0.0 + radius))
        
        context.strokePath()
        
        //四个半圆
        context.setLineDash(phase: 0, lengths: [1.5, 1.5])
        //左上角
        context.addArc(center: CGPoint(x: radius, y: radius), radius: radius, startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(-M_PI), clockwise: true)
        context.drawPath(using: .stroke)
        //左下角
        context.addArc(center: CGPoint(x: radius, y: size.height - radius), radius: radius, startAngle: CGFloat(-M_PI), endAngle: CGFloat(M_PI_2), clockwise: true)
        context.drawPath(using: .stroke)
        //右下角
        context.addArc(center: CGPoint(x: size.width - radius, y: size.height - radius), radius: radius, startAngle: CGFloat(M_PI_2), endAngle: CGFloat(0), clockwise: true)
        context.drawPath(using: .stroke)
        //右上角
        context.addArc(center: CGPoint(x: size.width - radius, y: radius), radius: radius, startAngle: CGFloat(0), endAngle: CGFloat(-M_PI_2), clockwise: true)
        
        context.drawPath(using: .stroke)
        
        let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image ?? UIImage()
    }
    
    //    等比率缩放
    public class func scale(_ image:UIImage, scale:CGFloat)->UIImage {
        let size = CGSize(width: image.size.width * scale, height: image.size.height * scale);
        
        return resSize(image, size:size);
    }
    
    //    重设图片大小
    public class func resSize(_ image:UIImage, size:CGSize)->UIImage {
        UIGraphicsBeginImageContextWithOptions(size,false,UIScreen.main.scale);
        image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height));
        let reSizeImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!;
        UIGraphicsEndImageContext();
        
        return reSizeImage;
    }
    
    //    截取部分图片
    public class func cutOut(_ image:UIImage, rect:CGRect)->UIImage {
        let sourceImage: CGImage = image.cgImage!
        let newCGImage = sourceImage.cropping(to: rect)!
        let newImage = UIImage.init(cgImage: newCGImage);
        
        return newImage;
    }
    
    //    高斯模糊滤镜
    public class func blurFilter(_ image:UIImage, blur:CGFloat)->UIImage {
        
        var blur = blur
        if blur < 0.0 || blur > 1.0 {
            blur = 0.5
        }
        var boxSize = Int(blur * 40)
        boxSize = boxSize - (boxSize % 2) + 1
        
        let img = image.cgImage
        
        var inBuffer = vImage_Buffer()
        var outBuffer = vImage_Buffer()
        var error: vImage_Error!
        var pixelBuffer: UnsafeMutableRawPointer
        
        // 从CGImage中获取数据
        let inProvider = img!.dataProvider
        let inBitmapData = inProvider!.data
        
        
        // 设置从CGImage获取对象的属性
        inBuffer.width = UInt(img!.width)
        inBuffer.height = UInt(img!.height)
        inBuffer.rowBytes = img!.bytesPerRow
        inBuffer.data = UnsafeMutableRawPointer(
            mutating:
            
            
            CFDataGetBytePtr(inBitmapData))
        pixelBuffer = malloc(img!.bytesPerRow * img!.height)
        
        outBuffer.data = pixelBuffer
        outBuffer.width = UInt(img!.width)
        outBuffer.height = UInt(img!.height)
        outBuffer.rowBytes = img!.bytesPerRow
        
        error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, UInt32(boxSize), UInt32(boxSize), nil, UInt32(kvImageEdgeExtend))
        if error != nil && error != 0 {
            NSLog("error from convolution %ld", error)
        }
        
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let ctx = CGContext(data: outBuffer.data, width: Int(outBuffer.width), height: Int(outBuffer.height), bitsPerComponent: 8, bytesPerRow: outBuffer.rowBytes, space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)
        
        let imageRef = ctx!.makeImage()!
        let returnImage = UIImage(cgImage: imageRef)
        return returnImage
    }
    
    
    ///将PHAsset对象转为UIImage对象
    public class func PHAssetToUIImage(asset: PHAsset, size: CGSize) -> UIImage {
        var image = UIImage()
        
        // 新建一个默认类型的图像管理器imageManager
        let imageManager = PHImageManager.default()
        
        // 新建一个PHImageRequestOptions对象
        let imageRequestOption = PHImageRequestOptions()
        
        // PHImageRequestOptions是否有效
        imageRequestOption.isSynchronous = true
        
        // 缩略图的压缩模式设置为无
        imageRequestOption.resizeMode = .none
        
        // 缩略图的质量为高质量，不管加载时间花多少
        imageRequestOption.deliveryMode = .highQualityFormat
        
        // 按照PHImageRequestOptions指定的规则取出图片
        imageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: imageRequestOption, resultHandler: {
            (result, _) -> Void in
            image = result!
        })
        return image
    }
    
public class func resetImage(_ sourceImg: UIImage?, maxWidth: CGFloat) -> UIImage? {
    let width: CGFloat?
    let height: CGFloat?
        
    if (sourceImg?.size.width)! <= maxWidth {
        return sourceImg
    }else {
        width = maxWidth
        height = maxWidth/((sourceImg?.size.width)!/(sourceImg?.size.height)!)
    }
    UIGraphicsBeginImageContext(CGSize(width: CGFloat(width!), height: CGFloat(height!)))
    sourceImg?.draw(in: CGRect(x: 0, y: 0, width: CGFloat(width!), height: CGFloat(height!)))
    let scaledImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return scaledImage
    }
//
//func getSquareImage(_ image: UIImage?) -> UIImage? {
//    let imgWidth = Float(image?.size.width ?? 0.0)
//    let imgHeight = Float(image?.size.height ?? 0.0)
//    let viewWidth: Float = imgWidth > imgHeight ? imgHeight : imgWidth
//    let rect = CGRect(x: CGFloat(((imgWidth - viewWidth) / 2)), y: CGFloat(((imgHeight - viewWidth) / 2)), width: CGFloat(viewWidth), height: CGFloat(viewWidth))
//    let subImageRef = image?.cgImage?.cropping(to: rect)
//    let smallBounds = CGRect(x: 0, y: 0, width: CGImageGetWidth(subImageRef!), height: CGImageGetHeight(subImageRef!))
//    let smallbouds = CGRect.init(x: 0, y: 0, width: subImageRef?.width, height: sub)
//    UIGraphicsBeginImageContext(smallBounds.size)
//    let context = UIGraphicsGetCurrentContext()
//    context?.draw(subImageRef!, in: smallBounds)
//    var smallImage: UIImage? = nil
//    if let aRef = subImageRef {
//        smallImage = UIImage(cgImage: aRef)
//    }
//    UIGraphicsEndImageContext()
//    return smallImage
//}
    
//    /**
//     照片竖拍  web显示旋转解决:图片大于2M会自动旋转90度
//     
//     - parameter aImage:
//     
//     - returns:
//     */
//    class func fixOrientation(aImage:UIImage)->UIImage  {
//        if aImage.imageOrientation == UIImageOrientation.up{
//            return aImage
//        }
//        
////        var transform = CGAffineTransformIdentity
//        
//        var transform: CGAffineTransform = .identity
//        
//        switch (aImage.imageOrientation) {
//        case .down,.downMirrored:
////            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height)
////            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
//            transform = CGAffineTransform.init(translationX: aImage.size.width, y: aImage.size.height)
//            transform = transform.rotated(by: CGFloat(M_PI))
//            break;
//            
//        case .left,.leftMirrored:
////            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
////            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
//            transform = CGAffineTransform.init(translationX: aImage.size.width, y: 0)
//            transform = transform.rotated(by: CGFloat(M_PI_2))
//            break;
//            
//        case .right,.rightMirrored:
////            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height)
////            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
//            transform = CGAffineTransform.init(translationX: 0, y: aImage.size.height)
//            transform = transform.rotated(by: CGFloat(-M_PI_2))
//            break;
//        default:
//            break;
//        }
//        
//        switch (aImage.imageOrientation) {
//        case .upMirrored,.downMirrored:
////            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
////            transform = CGAffineTransformScale(transform, -1, 1)
//            transform = CGAffineTransform.init(translationX: aImage.size.width, y: 0)
//            transform = transform.scaledBy(x: -1, y: 1)
//            break;
//            
//        case .leftMirrored,.rightMirrored:
//            transform = CGAffineTransform.init(translationX: 0, y: aImage.size.height)
//            transform = transform.scaledBy(x: -1, y: 1)
////            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0)
////            transform = CGAffineTransformScale(transform, -1, 1)
//            break;
//        default:
//            break;
//        }
//        
////        let ctx:CGContextRef = CGBitmapContextCreate(nil, Int(aImage.size.width), Int(aImage.size.height),
////                                                     CGImageGetBitsPerComponent(aImage.CGImage), 0,
////                                                     CGImageGetColorSpace(aImage.CGImage),
////                                                     1)!
//        
//        let ctx: CGContext = CGbit
//        
//        CGContextConcatCTM(ctx, transform)
//        switch (aImage.imageOrientation) {
//        case .left,.leftMirrored,.right,.rightMirrored:
////            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage)
//            break;
//            
//        default:
////            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
//            break;
//        }
//        
//        let cgimg:CGImage = CGBitmapContextCreateImage(ctx)!
//        let img:UIImage = UIImage.init(cgImage: cgimg)
//        return img;
//    }
}

